package com.tbit.uqbike.service.business.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.text.StrPool;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.tbit.uqbike.object.pojo.Machine;
import com.tbit.uqbike.object.pojo.UpKeepLog;
import com.tbit.uqbike.object.pojo.UpKeepTypeLog;
import com.tbit.uqbike.object.pojo.vo.UpKeepLogQueryReqVO;
import com.tbit.uqbike.object.pojo.vo.UpKeepLogReqVO;
import com.tbit.uqbike.object.pojo.vo.UpKeepLogRespVO;
import com.tbit.uqbike.object.value.LoginInfo;
import com.tbit.common.entity.view.PageResult;
import com.tbit.uqbike.service.base.TokenService;
import com.tbit.uqbike.service.business.UpKeepLogService;
import com.tbit.uqbike.service.business.UpKeepTypeLogService;
import com.tbit.uqbike.webmanager.business.machine_op_log.service.MachineOpLogService;
import com.tbit.uqbike.webmanager.dao.log.UpKeepLogDao;
import com.tbit.utils.DateTimeUtil;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.time.Duration;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author yao
 * @since 2025/1/23 10:05
 */
@Service
public class UpKeepLogServiceImpl implements UpKeepLogService {

    @Resource
    private UpKeepLogDao upKeepLogDao;

    @Resource
    private UpKeepTypeLogService upKeepTypeLogService;

    @Resource
    private TokenService tokenService;

    @Resource
    private MachineOpLogService machineOpLogService;

    @Override
    public PageResult<UpKeepLogRespVO> getPage(UpKeepLogQueryReqVO reqVO) {
        Page<UpKeepLogRespVO> page = new Page<>(reqVO.getPageNO(), reqVO.getRowCount());
        page = upKeepLogDao.selectPage(page, reqVO);
        List<UpKeepLogRespVO> list = page.getRecords();

        List<Integer> upKeepLogIds = list.stream().map(UpKeepLogRespVO::getId).collect(Collectors.toList());
        Map<Integer, List<UpKeepTypeLog>> upKeepLogMap = upKeepTypeLogService.getByUpKeepLogIds(upKeepLogIds);

        list.forEach(upKeepLog -> {
            List<UpKeepTypeLog> upKeepLogs = upKeepLogMap.getOrDefault(upKeepLog.getId(), Collections.emptyList());
            String upKeepTypes = joinUpKeepType(upKeepLogs);
            upKeepLog.setUpKeepTypes(upKeepTypes);
            upKeepLog.MConvertKM();
        });

        return PageResult.convertPage(page);
    }

    private String joinUpKeepType(List<UpKeepTypeLog> upKeepTypeLogMap) {
        return upKeepTypeLogMap.stream().map(UpKeepTypeLog::getUpKeepType).map(String::valueOf).collect(Collectors.joining(StrPool.COMMA));
    }

    @Override
    public List<UpKeepLogRespVO> getDateList(UpKeepLogQueryReqVO reqVO) {
        List<UpKeepLogRespVO> list = upKeepLogDao.selectDateList(reqVO);

        // 获取日期列表
        List<String> dates = list.stream().map(UpKeepLogRespVO::getDate).collect(Collectors.toList());

        String now = DateTimeUtil.getNowTime();
        String startTime = Optional.ofNullable(reqVO.getStartTime()).orElse(now);
        String endTime = Optional.ofNullable(reqVO.getEndTime()).orElse(now);

        LocalDateTime startLocalDate = LocalDateTime.parse(startTime, DatePattern.NORM_DATETIME_FORMATTER);
        LocalDateTime endLocalDate = LocalDateTime.parse(endTime, DatePattern.NORM_DATETIME_FORMATTER);

        // 计算两个日期之间的天数
        long days = Duration.between(startLocalDate, endLocalDate).toDays();

        // 补全缺失的日期
        for (long i = 0; i <= days; i++) {
            String date = startLocalDate.plusDays(i).format(DatePattern.NORM_DATE_FORMATTER);
            // 如果日期不存在则添加
            if (!dates.contains(date)) {
                list.add(UpKeepLogRespVO.of(date));
            }
        }

        // 根据时间排序
        list.sort(Comparator.comparing(upKeepLogRespVO -> {
            upKeepLogRespVO.MConvertKM();
            return upKeepLogRespVO.getDate();
        }));
        return list;
    }

    @Override
    public PageResult<UpKeepLogRespVO> getCountPage(UpKeepLogQueryReqVO reqVO) {
        Page<UpKeepLogRespVO> page = new Page<>(reqVO.getPageNO(), reqVO.getRowCount());
        page = upKeepLogDao.selectCountPage(page, reqVO);
        if (CollectionUtils.isNotEmpty(page.getRecords())){
            for (UpKeepLogRespVO upKeepLogRespVO : page.getRecords()) {
                upKeepLogRespVO.MConvertKM();
            }
        }
        return PageResult.convertPage(page);
    }

    @Override
    public UpKeepLogRespVO getById(Integer id) {
        UpKeepLog upKeepLog = upKeepLogDao.selectById(id);
        if (upKeepLog == null) {
            return null;
        }
        UpKeepLogRespVO bean = BeanUtil.toBean(upKeepLog, UpKeepLogRespVO.class);
        String upKeepTypes = joinUpKeepType(upKeepTypeLogService.getByUpKeepLogId(upKeepLog.getId()));
        bean.setUpKeepTypes(upKeepTypes);
        bean.MConvertKM();
        return bean;
    }

    @Override
    public void update(UpKeepLogReqVO reqVO) {

        UpKeepLog upKeepLog = upKeepLogDao.selectById(reqVO.getId());
        if (upKeepLog == null) {
            return;
        }

        UpKeepLog upKeepLogCopy = BeanUtil.toBean(reqVO, UpKeepLog.class);

        LoginInfo loginInfo = tokenService.getLoginInfo();

        Machine machine = new Machine();
        machine.setAccountid(upKeepLog.getAccountId());
        machine.setMachineid(upKeepLog.getMachineId());
        machine.setMachineno(upKeepLog.getMachineNo());
        machine.setUsercode(upKeepLog.getUserCode());

        // 插入车辆操作日志
        machineOpLogService.batchAddRecord(
                "保养",
                String.format("变更状态[%d->%d]",
                        upKeepLog.getStatus(),
                        reqVO.getStatus()),
                true,
                "",
                Collections.singletonList(machine));

        upKeepLogCopy.setUpdater(loginInfo.getAccountUserId().toString());
        upKeepLogCopy.setUpdateTime(new Date());

        upKeepLogDao.updateById(upKeepLogCopy);
    }
}
